#include "userMain.h"
#include "userA_IIC.h"
/**********************************************?????***************************************************/

//#define Ax_ASK_Test_Error     

#ifdef  Ax_ASK_Test_Error
#define Ax_ASK_Test_Error
unsigned int Ax_Right_Count = 0;
unsigned int Ax_Error_Count = 0;

#endif

/*IIC time sequence*/
#define     Ax_THD_STA     4            // time of SCL&SDA keep start level 
#define     Ax_TSU_STA     4            //time of SDA start condition
#define     Ax_TYLOW       2            // time of SCL output low level (half of TLOW)
#define     Ax_THIGH       4            //time of SDA output high level
#define     Ax_THHIGN      2            //time of SDA output high level: half
#define     Ax_TSU_STO     4            //time of establish SDA stop condition
#define     Ax_TBUF        8            //time of bus release

#define     Delay_us_2		_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP
#define     Delay_us_4		Delay_us_2;Delay_us_2
#define     Delay_us_8		Delay_us_4;Delay_us_4

#define     Dely_us_Ax_THD_STA			Delay_us_4
#define     Dely_us_Ax_TSU_STA			Delay_us_4
#define     Dely_us_Ax_TYLOW			Delay_us_2
#define     Dely_us_Ax_THIGH			Delay_us_4
#define     Dely_us_Ax_THHIGN			Delay_us_2
#define     Dely_us_Ax_TSU_STO			Delay_us_4
#define     Dely_us_Ax_TBUF				Delay_us_8

/***********************************************************************************************************/
/*SDA and SCL IO configure*/
#define     Ax_I2C_SDA_PORT     GPIOB
#define	    Ax_I2C_SDA_PIN	GPIO_Pin_4
#define     Ax_I2C_SCL_PORT     GPIOB
#define	    Ax_I2C_SCL_PIN	GPIO_Pin_5
#define     Ax_SDA_1       	    GPIO_SetBits(Ax_I2C_SDA_PORT,Ax_I2C_SDA_PIN)
#define     Ax_SDA_0       	    GPIO_ResetBits(Ax_I2C_SDA_PORT,Ax_I2C_SDA_PIN)
#define     Ax_SCL_1            GPIO_SetBits(Ax_I2C_SCL_PORT,Ax_I2C_SCL_PIN)
#define     Ax_SCL_0            GPIO_ResetBits(Ax_I2C_SCL_PORT,Ax_I2C_SCL_PIN)
#define     Ax_SDA_IN           GPIO_ReadInputDataBit(Ax_I2C_SDA_PORT,Ax_I2C_SDA_PIN)
/***********************************************************************************************************/
void Ax_OUT_SDA_config(void);
void Ax_IN_SDA_config(void);
void Ax_OUT_SCL_config(void);
void Ax_IN_SCL_config(void);

void Ax_OUT_SDA_config(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
    GPIO_InitStructure.GPIO_Pin = Ax_I2C_SDA_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(Ax_I2C_SDA_PORT, &GPIO_InitStructure);
}

void Ax_IN_SDA_config(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
    GPIO_InitStructure.GPIO_Pin = Ax_I2C_SDA_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(Ax_I2C_SDA_PORT, &GPIO_InitStructure);
}

void Ax_OUT_SCL_config(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
    GPIO_InitStructure.GPIO_Pin = Ax_I2C_SCL_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(Ax_I2C_SCL_PORT, &GPIO_InitStructure);
}

void Ax_IN_SCL_config(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
    GPIO_InitStructure.GPIO_Pin = Ax_I2C_SCL_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(Ax_I2C_SCL_PORT, &GPIO_InitStructure);
}

/*IIC initial function*/ 
void Ax_IIC_Initial(void)
{
    Ax_OUT_SCL_config(); 
    Ax_OUT_SDA_config();
    Ax_SDA_1;
    Ax_SCL_1;    
  }

/*IIC start function */
void Ax_IIC_Start(void)
{
    Ax_OUT_SDA_config();
    Ax_SCL_1;
    Ax_SDA_1;
  	Dely_us_Ax_TSU_STA;
    Ax_SDA_0;
    Dely_us_Ax_THD_STA;
    Ax_SCL_0;
    Ax_SDA_0;
    Dely_us_Ax_TYLOW;  
}

/*IIC stop function*/
void Ax_IIC_Stop(void)
{
    Ax_OUT_SDA_config();
    Ax_SCL_0;
    Ax_SDA_0;  
    Dely_us_Ax_TYLOW;  
    Ax_SCL_1;
    Dely_us_Ax_TSU_STO;
    Ax_SDA_1;
    Dely_us_Ax_TBUF;
    Ax_SCL_0;
}

/*IIC Master ack function*/
/**************************************************/
void Ax_Ack(void)
{
    Ax_OUT_SDA_config();
    Ax_SCL_0;
    Ax_SDA_0;
    Dely_us_Ax_TYLOW;
    Ax_SCL_1;
    Dely_us_Ax_THIGH;
    Ax_SCL_0;
    Ax_SDA_1;
    Dely_us_Ax_TYLOW;
}
/*IIC Master no ack function*/
/*************************************************/
void Ax_NoAck(void)  
{
    Ax_OUT_SDA_config();
    Ax_SCL_0;
    Ax_SDA_1;
    Dely_us_Ax_TYLOW;
    Ax_SCL_1;
    Dely_us_Ax_THIGH;
    Ax_SCL_0;
    Ax_SDA_0;
    Dely_us_Ax_TYLOW;
}
/*IIC Master ack Test function*/
unsigned char Ax_TestAck(void)     
{ 
    int Ax_IIC_ACK_TEST;
    Ax_IN_SDA_config();
    Ax_SCL_0;
    Dely_us_Ax_TYLOW;
    Ax_SCL_1;
    Dely_us_Ax_THIGH;
  
    if(Ax_SDA_IN==0x00)
    {
        Ax_IIC_ACK_TEST=0;
        #ifdef Ax_ASK_Test_Error
        #define Ax_ASK_Test_Error
        Ax_Right_Count++;
        #endif
    }
    else
    {
        Ax_IIC_ACK_TEST=1;
        #ifdef Ax_ASK_Test_Error
        #define Ax_ASK_Test_Error
        Ax_Error_Count++;
        #endif
    }
  
    Ax_SCL_0;
    return Ax_IIC_ACK_TEST;
}
/*write one byte(8 bits)*/
void Ax_Write8Bit(unsigned char Ax_input)
{
    int Ax_temp;
    Ax_OUT_SDA_config();
    for(Ax_temp=8;Ax_temp>0;Ax_temp--)
    {   
        Ax_SCL_0;
        if((Ax_input&0x80)==0)
            Ax_SDA_0;
        else
            Ax_SDA_1;
        Dely_us_Ax_TYLOW;
        Ax_SCL_1; 
        Dely_us_Ax_THIGH;
        Ax_SCL_0;
        Dely_us_Ax_TYLOW;
        Ax_input=Ax_input<<1;
    }
}
/*read one byte (8 bits)*/
/****************************************************/
unsigned char Ax_Read8Bit(void)    
{
    int Ax_temp;
    unsigned char Ax_rbyte=0x00;
    Ax_IN_SDA_config();
    for(Ax_temp=8;Ax_temp>0;Ax_temp--)
    {
        Ax_SCL_0;
        Dely_us_Ax_TYLOW;
        Ax_SCL_1;
        Dely_us_Ax_THHIGN;
        Ax_rbyte=Ax_rbyte<<1;
        if(Ax_SDA_IN==0x00)
            Ax_rbyte=Ax_rbyte|0x00;
        else
            Ax_rbyte=Ax_rbyte|0x01;
        Dely_us_Ax_THHIGN;    
        Ax_SCL_0;
        Dely_us_Ax_TYLOW;
    }
    return(Ax_rbyte);
}
/***********IIC IO Release*********************/
void Ax_IIC_End(void)
{
    Dely_us_Ax_TBUF;
    Ax_IN_SCL_config();
    Ax_IN_SDA_config();
    Dely_us_Ax_TBUF;
}